Public Class IrcConnection
    Implements Core.Connection


    Private _host As Net.IPAddress
    Private _port As Integer
    Private _connection As Core.Connection
    Private WithEvents _socket As System.Net.Sockets.TcpClient
    'Private WithEvents _socket As System.Net.Sockets.Socket
    Private Const READ_BUFFER_SIZE As Integer = 255
    Private readBuffer(READ_BUFFER_SIZE) As Byte
    Private _nick As String
    Private _username As String
    Private receiveThread As Threading.Thread

    Public Event dataReceived(ByVal data As Byte()) Implements Core.Connection.dataReceived
    Public Event dataSent(ByVal data As String) Implements Core.Connection.dataSent

    Public Sub New()
        '_socket = New Net.Sockets.Socket(Net.Sockets.AddressFamily.InterNetwork, Net.Sockets.SocketType.Stream, Net.Sockets.ProtocolType.Tcp)
        _socket = New Net.Sockets.TcpClient()
    End Sub
    Public Sub New(ByVal host As Net.IPAddress, ByVal port As Integer)
        '_socket = New Net.Sockets.Socket(Net.Sockets.AddressFamily.InterNetwork, Net.Sockets.SocketType.Stream, Net.Sockets.ProtocolType.Tcp)
        _socket = New Net.Sockets.TcpClient()
        _host = host
        _port = port
    End Sub

#Region "Overrides"
    Public Property Host() As System.Net.IPAddress Implements Core.Connection.Host
        Get
            Return _host
        End Get
        Set(ByVal value As System.Net.IPAddress)
            _host = value
        End Set
    End Property

    Public Property Port() As Integer Implements Core.Connection.Port
        Get
            Return _port
        End Get
        Set(ByVal value As Integer)
            _port = value
        End Set
    End Property
    Public Sub Connect() Implements Core.Connection.Connect
        _socket.Connect(New Net.IPEndPoint(_host, _port))
        '_socket.GetStream.BeginRead(readBuffer, 0, READ_BUFFER_SIZE, AddressOf DoRead, Nothing)
        receiveThread = New Threading.Thread(New Threading.ThreadStart(AddressOf Receive))
        receiveThread.SetApartmentState(Threading.ApartmentState.MTA)
        receiveThread.Start()
        Login(_username, _nick)
    End Sub
    Public Sub close() Implements Core.Connection.close
        receiveThread.Abort()
        _socket.Close()
    End Sub
#End Region
#Region "Privados"

    Private Sub send(ByVal package As Core.Package) Implements Core.Connection.Send
        'Console.WriteLine("Sent package size: " + package.rawData.Length)
        '_socket.SendTo(package.rawData, System.Net.Sockets.SocketFlags.None, New Net.IPEndPoint(_host, _port))
        _socket.GetStream.Write(package.rawData, 0, package.rawData.Length)
        RaiseEvent dataSent(Text.Encoding.ASCII.GetString(package.rawData))
    End Sub
    Private Sub send(ByVal message As String) Implements Core.Connection.Send
        'Console.WriteLine("Sent :" + message)
        '_socket.SendTo(Text.Encoding.ASCII.GetBytes(message), System.Net.Sockets.SocketFlags.None, New Net.IPEndPoint(_host, _port))
        _socket.GetStream.Write(Text.Encoding.ASCII.GetBytes(message), 0, Text.Encoding.ASCII.GetBytes(message).Length)
        RaiseEvent dataSent(message)
    End Sub
#End Region


    Public Property Nick() As String
        Get
            Return _nick
        End Get
        Set(ByVal value As String)
            _nick = value
        End Set
    End Property
    Public Property Username() As String
        Get
            Return _username
        End Get
        Set(ByVal value As String)
            _username = value
        End Set
    End Property


    Sub SendCommand(ByVal command As String)
        send(command & vbCrLf)
    End Sub

    Private Sub Receive()
        Dim dataRead As Boolean = False
        Try
            While _socket.Connected
                dataRead = (_socket.GetStream.Read(readBuffer, 0, READ_BUFFER_SIZE) > 0)
                If Not dataRead Then
                    Exit Sub
                End If
                RaiseEvent dataReceived(readBuffer)
                Console.WriteLine("Received: " + Text.Encoding.ASCII.GetString(readBuffer))
                Array.Clear(readBuffer, 0, READ_BUFFER_SIZE)
            End While
        Catch ex As Exception
            Throw ex
        End Try
    End Sub
    Sub Login(ByVal User As String, ByVal Nick As String)
        send("USER " & User & " 0 * :" & User & vbCrLf)
        'USER {0} {1} * :{2}
        send("NICK " & Nick & vbCrLf)
        Join("Hackerss")
    End Sub
    Sub Join(ByVal Channel As String)
        send("JOIN #" & Channel & vbCrLf)
    End Sub
    'Private Sub DoRead(ByVal ar As IAsyncResult)
    '    Dim dataRead As Boolean = False
    '    Try
    '        dataRead = (_socket.GetStream.EndRead(ar) > 0)
    '        If Not dataRead Then
    '            'MarkAsDisconnected()
    '            Exit Sub
    '        End If
    '        RaiseEvent dataReceived(readBuffer)
    '        Console.WriteLine("Received: " + Text.Encoding.ASCII.GetString(readBuffer))
    '    Catch e As Exception
    '        Throw e
    '    Finally
    '        _socket.GetStream.BeginRead(readBuffer, 0, READ_BUFFER_SIZE, AddressOf DoRead, Nothing)
    '    End Try
    'End Sub


End Class
